package cc.vv.party.init

import cc.vv.party.beans.model.*
import cc.vv.party.common.constants.AdminInfo
import cc.vv.party.common.constants.SysConsts
import cc.vv.party.common.constants.enums.OrgType
import cc.vv.party.common.constants.enums.RoleType
import cc.vv.party.service.*
import com.alibaba.fastjson.JSONObject
import com.baomidou.mybatisplus.mapper.EntityWrapper
import commonx.core.json.toJSONObject
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.ApplicationArguments
import org.springframework.boot.ApplicationRunner
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
import java.io.BufferedInputStream

/**
 * @version 1.0.0
 * @author: Gyb
 * @date 2018-10-13
 * @description
 **/
@Component
class InitDataRunner(@Value("\${spring.init-data}") var initData: Boolean) : ApplicationRunner {

    private val logger by lazy { LoggerFactory.getLogger(InitDataRunner::class.java) }

    @Autowired
    lateinit var roleService: RoleService

    @Autowired
    lateinit var rolePermissionService: RolePermissionService

    @Autowired
    lateinit var permissionService: PermissionService

    @Autowired
    lateinit var userRoleService: UserRoleService

    @Autowired
    lateinit var orgService: OrgService

    @Autowired
    lateinit var orgAdminService: OrgAdminService

    @Transactional
    override fun run(args: ApplicationArguments?) {
        AdminInfo.initAdmin()
        if (!initData) return
        deleteData()
        initData()
    }

    private fun initData() {
        readMenuJson()
        readRoleJson()
        initUserRole()
        //如果根组织机构存在，即宝塔区存在，则不需要执行
//        initRootOrg()
        //不需要初始化
//        initOrgAdmin()
    }

    private fun deleteData() {
        roleService.delete(EntityWrapper())
        rolePermissionService.delete(EntityWrapper())
        permissionService.delete(EntityWrapper())
        userRoleService.delete(EntityWrapper())
        orgAdminService.delete(EntityWrapper())
    }

    private fun initUserRole() {
        val ur = UserRole()
        ur.userAccount = AdminInfo.admin!!.name
        ur.roleId = AdminInfo.admin!!.role
        ur.createUser = AdminInfo.admin!!.id
        userRoleService.insert(ur)
    }

    private fun readMenuJson() {
        val menu = readJsonFile("/data/menu.json")
        val json = JSONObject.parseArray(menu)
        val permissionList = mutableListOf<Permission>()
        for (obj in json) {
            val node = obj as JSONObject
            val permission = Permission()
            permission.id = node.getString("id")
            permission.name = node.getString("name")
            permission.type = node.getString("type")
            permission.parentId = "00"
            permission.path = "宝塔区党建.${permission.name}"
            permission.createUser = AdminInfo.admin!!.id
            permissionList.add(permission)
            buildChildren(permission, node, permissionList)
        }
        permissionService.insertBatch(permissionList)
    }

    private fun initRootOrg() {
        val org = Org()
        org.id = SysConsts.BAOTA_AREA_ID
        org.parentId = "0"
        org.name = "宝塔区"
        org.mobile = "13000000000"
        org.type = OrgType.AREA
        org.path = org.id
        org.introduction = "宝塔区简介"
        org.createUser = "5b67335096f1466e83313ff316101376"
        orgService.insert(org)
    }
//
//    private fun initOrgAdmin() {
//        val orgAdmin = OrgAdmin()
//        orgAdmin.id = "4876a10d49ac483795e54fc958bd3577"
//        orgAdmin.orgId = SysConsts.BAOTA_AREA_ID
//        orgAdmin.userAccount = "admin"
//        orgAdmin.userName = "管理员"
//        orgAdmin.createUser = "5b67335096f1466e83313ff316101376"
//        orgAdminService.insert(orgAdmin)
//    }

    private fun buildChildren(parent: Permission, node: JSONObject, permissionList: MutableList<Permission>) {
        if (node["children"] == null) {
            return
        }
        val children = node.getJSONArray("children")
        for (o in children) {
            val child = o as JSONObject
            val permission = Permission()
            permission.id = child.getString("id")
            permission.name = child.getString("name")
            permission.type = child.getString("type")
            permission.parentId = parent.id
            permission.path = "${parent.path}.${permission.name}"
            permission.createUser = AdminInfo.admin!!.id
            permissionList.add(permission)
            buildChildren(permission, child, permissionList)
        }
    }

    private fun readRoleJson() {
        val roleJson = readJsonFile("/data/role.json")
        val roleArray = JSONObject.parseArray(roleJson)
        val rolePermissionList = mutableListOf<RolePermission>()
        val roleList = roleArray.map {
            val json = it as JSONObject
            val role = Role()
            role.id = json.getString("id")
            role.name = json.getString("name")
            role.type = RoleType.enumOf(json.getString("type"))
            role.description = json.getString("name")
            role.createUser = AdminInfo.admin!!.id
            val ps = json.getJSONArray("permission")
            for (p in ps) {
                val rp = RolePermission()
                rp.roleId = role.id
                rp.permissionId = p.toString()
                rp.createUser = AdminInfo.admin!!.id
                rolePermissionList.add(rp)
            }
            role
        }.toList()
        roleService.insertBatch(roleList)
        rolePermissionService.insertBatch(rolePermissionList)
    }

    private fun readJsonFile(path: String): String {
        val stream = javaClass.getResourceAsStream(path)
        val buffer = BufferedInputStream(stream).bufferedReader()
        val lines = buffer.readLines()
        return lines.joinToString(separator = "")
    }
}